home *** CD-ROM | disk | FTP | other *** search
- -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C)
- -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
- --
- deferred class COLLECTION[E]
- --
- -- Such a collection is a traversable one using INTEGER indexing
- -- from `lower' to `upper'.
- -- Standard ARRAY[E] inherit from COLLECTION[E].
- --
-
- inherit
- ANY
- undefine copy
- redefine is_equal, print_attributes_on
- end;
-
- feature -- Indexing :
-
- lower: INTEGER is
- -- Lower index bound.
- deferred
- end;
-
- upper: INTEGER is
- -- Upper index bound.
- deferred
- end;
-
- valid_index(index: INTEGER): BOOLEAN is
- -- True when `index' is valid (ie inside actual bounds).
- do
- Result := lower <= index and then index <= upper;
- ensure
- Result = (lower <= index and index <= upper);
- end;
-
- count: INTEGER is
- -- Length of index interval.
- do
- Result := upper - lower + 1;
- end;
-
- empty: BOOLEAN is
- -- Is collection empty?
- do
- Result := (count = 0);
- end;
-
- feature -- Accessing :
-
- infix "@", item(index: INTEGER): E is
- -- Item at position `index'.
- require
- inside_bounds: valid_index(index)
- deferred
- end;
-
- first: E is
- require
- count >= 1
- do
- Result := item(lower);
- end;
-
- last: E is
- require
- count >= 1
- do
- Result := item(upper);
- end;
-
- feature -- Writing :
-
- put(element: E; index: INTEGER) is
- -- Put `element' at position `index'.
- require
- valid_index(index)
- deferred
- ensure
- item(index) = element
- end;
-
- swap(i1, i2: INTEGER) is
- require
- valid_index(i1);
- valid_index(i2);
- local
- tmp: E;
- -- *** WHAT ABOUT like item ?
- do
- tmp := item(i1);
- put(item(i2),i1);
- put(tmp,i2);
- ensure
- item(i1) = old item(i2);
- item(i2) = old item(i1);
- end;
-
- set_all_with(v: E) is
- -- Set all item with `v'.
- local
- i: INTEGER;
- do
- from
- i := upper;
- until
- i < lower
- loop
- put(v,i);
- i := i - 1;
- end;
- ensure
- count = old count
- end;
-
- set_slice_with(v: E; lower_index, upper_index: INTEGER) is
- -- Set all item with `v'.
- require
- lower_index <= upper_index;
- valid_index(lower_index);
- valid_index(upper_index);
- local
- i: INTEGER;
- do
- from
- i := lower_index;
- until
- i > upper_index
- loop
- put(v,i);
- i := i + 1;
- end;
- ensure
- count = old count
- end;
-
- clear_all is
- -- Set all items to default values.
- local
- value: E;
- do
- set_all_with(value);
- ensure
- count = old count;
- end;
-
- feature -- Looking and Searching :
-
- has(x: E): BOOLEAN is
- -- Look for `x' using `equal'.
- do
- Result := (index_of(x) /= upper + 1);
- end;
-
- fast_has(x: E): BOOLEAN is
- -- Same as `has' but use `='.
- do
- Result := (fast_index_of(x) /= upper + 1);
- end;
-
- index_of(x: E): INTEGER is
- -- Give the index of the first occurrence of `x' using `equal'.
- -- Answer `upper + 1' when `x' is not inside.
- do
- from
- Result := lower;
- until
- (Result > upper) or else equal_like(x,item(Result))
- loop
- Result := Result + 1;
- end;
- ensure
- lower <= Result;
- Result <= upper + 1;
- Result <= upper implies equal(x,item(Result));
- end;
-
- fast_index_of(x: E): INTEGER is
- -- Same as `index_of' but use `=' for comparison.
- do
- from
- Result := lower;
- until
- (Result > upper) or else x = item(Result)
- loop
- Result := Result + 1;
- end;
- ensure
- lower <= Result;
- Result <= upper + 1;
- Result <= upper implies x = item(Result);
- end;
-
- feature -- Looking and comparison :
-
- is_equal(other: like Current): BOOLEAN is
- -- Use `equal' to compare elements.
- local
- i: INTEGER;
- e1, e2: E;
- do
- if Current = other then
- Result := true;
- elseif lower = other.lower and then
- upper = other.upper then
- from
- Result := true;
- i := lower;
- until
- i > upper or not Result
- loop
- Result := equal_like(item(i),other.item(i));
- i := i + 1;
- end;
- end;
- end;
-
- all_cleared: BOOLEAN is
- -- Are all items set to default values?
- local
- value: E;
- i: INTEGER;
- do
- from
- Result := true;
- i := lower;
- until
- i > upper
- loop
- Result := value = item(i);
- if Result then
- i := i + 1;
- else
- i := upper + 1;
- end;
- end;
- end;
-
- nb_occurrences(elt: E): INTEGER is
- -- Number of occurrences using `equal'.
- -- See also `fast_nb_occurrences' to chose
- -- the apropriate one.
- local
- i: INTEGER;
- do
- from
- i := lower;
- until
- i > upper
- loop
- if equal_like(elt,item(i)) then
- Result := Result + 1;
- end;
- i := i + 1;
- end;
- ensure
- Result >= 0;
- end;
-
- fast_nb_occurrences(elt: E): INTEGER is
- -- Number of occurrences using `='.
- local
- i: INTEGER;
- do
- from
- i := lower;
- until
- i > upper
- loop
- if elt = item(i) then
- Result := Result + 1;
- end;
- i := i + 1;
- end;
- ensure
- Result >= 0;
- end;
-
- feature -- Printing :
-
- print_attributes_on(file: STD_FILE_WRITE) is
- local
- counter, i: INTEGER;
- v: like item;
- do
- file.put_string("lower: ");
- file.put_integer(lower);
- file.put_string(" upper: ");
- file.put_integer(upper);
- file.put_string(" [");
- from
- i := lower;
- counter := 10;
- until
- i > upper or else counter = 0
- loop
- v := item(i);
- if v.is_expanded_type then
- v.print_on(file);
- elseif ("STRING").is_equal(v.generator) then
- v.print_on(file);
- else
- file.put_string(v.generating_type);
- file.put_character('#');
- file.put_integer(v.object_id);
- end;
- if i < upper then
- file.put_character(' ');
- end;
- i := i + 1;
- counter := counter - 1;
- end;
- if i <= upper then
- file.put_string(" ...");
- end;
- file.put_character(']');
- end;
-
- feature -- Other Features :
-
- clear is
- -- Discard all items.
- deferred
- ensure
- empty;
- end;
-
- replace_all(x, r: E) is
- local
- i: INTEGER;
- do
- from
- i := lower;
- until
- i > upper
- loop
- if equal_like(item(i),x) then
- put(r,i);
- end;
- i := i + 1;
- end;
- end;
-
- fast_replace_all(x, r: E) is
- local
- i: INTEGER;
- do
- from
- i := lower;
- until
- i > upper
- loop
- if item(i) = x then
- put(r, i);
- end;
- i := i + 1;
- end;
- end;
-
- move(lower_index, upper_index, distance: INTEGER) is
- -- Move Range `lower_index' .. `upper_index' by `distance'
- -- positions. Negative distance moves towards lower indices.
- -- Free places get default values.
- require
- lower_index <= upper_index;
- valid_index(lower_index);
- valid_index(lower_index + distance);
- valid_index(upper_index);
- valid_index(upper_index + distance);
- local
- default_value: E;
- i: INTEGER;
- do
- if distance < 0 then
- from
- i := lower_index;
- until
- i > upper_index
- loop
- put(item(i),i + distance);
- put(default_value,i);
- i := i + 1;
- end;
- elseif distance > 0 then
- from
- i := upper_index;
- until
- i < lower_index
- loop
- put(item(i),i + distance);
- put(default_value,i);
- i := i - 1;
- end;
- end;
- end;
-
- feature {NONE}
-
- equal_like(e1, e2: E): BOOLEAN is
- -- Note: to avoid calling `equal' :-(
- -- Because SmallEiffel is not yet able to infer
- -- arguments types.
- do
- if e1.is_expanded_type then
- Result := e1 = e2 or else e1.is_equal(e2);
- -- *******
- -- Problem with post-condition of ELKS standard_is_equal.
- -- same_type is always false when receiver is an expanded
- -- type.
- elseif e1 = e2 then
- Result := true;
- elseif e1 = Void or else e2 = Void then
- else
- Result := e1.is_equal(e2);
- end;
- end;
-
- end -- COLLECTION
-